package com.hezhou.jenkins.my_jenkins_test.controller;

import cn.hutool.core.util.StrUtil;
import com.hezhou.jenkins.my_jenkins_test.json.CodeMsg;
import com.hezhou.jenkins.my_jenkins_test.json.HeZhouResult;
import com.hezhou.jenkins.my_jenkins_test.vo.response.RspFileUpload;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * ---------------------------
 * (FastDfsController) 文件上传控制层
 * ---------------------------
 *
 * @Author: [hezhou]
 * @Date: 2020/4/20
 * @Version: [1.0.1]
 * ---------------------------
 */
@Controller
@Api(value = "文件上传swagger api")
public class FastDfsController {

    public static final Logger log = LoggerFactory.getLogger(FastDfsController.class);

    /**
     * 上传文件到FastDFS
     *
     * @param file
     */
    @RequestMapping(value = "/fastDFSUpload", method = RequestMethod.POST)
    @ApiOperation(value = "上传文件到FastDFS", notes = "notes")
    @ResponseBody
    public HeZhouResult<RspFileUpload> fastDFSUpload(@RequestParam("file") MultipartFile file) {
        String ext_Name = file.getOriginalFilename().split("\\.")[1];
        String file_Name = file.getOriginalFilename().split("\\.")[0];
        byte[] bytes = null;
        try {
            bytes = file.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath= uploadFile(bytes, ext_Name, file_Name);
        //组装文件信息
        RspFileUpload rspFileUpload = new RspFileUpload();
        rspFileUpload.setFileUrl(filePath);
        rspFileUpload.setFileName(file_Name);
        rspFileUpload.setFileSuffixName(ext_Name);
        rspFileUpload.setFileSize(file.getSize());
        return HeZhouResult.success(rspFileUpload);
    }

    /**
     * 上传文件
     * @param byteFile
     * @param ext_file
     * @param file_Name
     * @return
     */
    public String uploadFile(byte[] byteFile, String ext_file, String file_Name) {

        // 拼接服务区的文件路径
        StringBuffer sbPath = new StringBuffer();
        sbPath.append("http://192.168.121.130/");
        try {
            // 初始化文件资源
            ClientGlobal.initByProperties("application.properties");

            // 链接FastDFS服务器，创建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();

            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            //保存文件信息  方便下载时拿取
            NameValuePair[] nvps = new NameValuePair[1];
            nvps[0] = new NameValuePair(file_Name, ext_file);
            //利用字节流上传文件
            String[] strings = storageClient.upload_file(byteFile, ext_file, nvps);
            sbPath.append(StrUtil.join("/", strings));
        } catch (IOException | MyException e) {
            e.printStackTrace();
        }
        return sbPath.toString();
    }

    /**
     * 获得可用的storage IP
     *
     * @param trackerClient
     * @param trackerServer
     * @return 返回storage IP
     */
    private static String getStorageServerIp(TrackerClient trackerClient, TrackerServer trackerServer) {
        String storageIp = null;
        if (trackerClient != null && trackerServer != null) {
            try {
                StorageServer storageServer = trackerClient.getStoreStorage(trackerServer, "group1");
                storageIp = storageServer.getSocket().getInetAddress().getHostAddress();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return storageIp;
    }

    /**
     * 得到Storage服务
     *
     * @param storageIp
     * @return 返回Storage服务
     */
    private static StorageServer getStorageServer(String storageIp) {
        StorageServer storageServer = null;
        if (storageIp != null && !("").equals(storageIp)) {
            try {
                // ip port store_path下标
                storageServer = new StorageServer(storageIp, 23000, 0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.debug("——storage server生成");
        return storageServer;
    }

    /**
     * FastDFS实现删除文件
     */
    @RequestMapping(value = "/fastDFSDelete", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "上传文件到FastDFS", notes = "notes")
    public HeZhouResult<?> fastDFSDelete(String filePath) {
        try {
            // 链接FastDFS服务器，创建tracker和Stroage
            ClientGlobal.initByProperties("application.properties");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();

            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            //filePath 格式 M00/00/00/wKh5gF6BijeAAP5lABRhiMzvTik390.png
            int group1 = storageClient.delete_file("group1", filePath);
            if (group1!=0){
                return HeZhouResult.error(CodeMsg.NOT_FIND_DATA,"删除失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return HeZhouResult.error(CodeMsg.NOT_FIND_DATA,e.getMessage());
        }
        return HeZhouResult.success();
    }

    /**
     * FastDFS实现文件下载
     *
     * @param filePath
     */
    @RequestMapping(value = "/fastDFSDownload", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "上传文件到FastDFS", notes = "notes")
    public HeZhouResult<?> fastDFSDownload(String filePath) {
        String localFilename = "E:\\fast_download";
        String groupName = "group1";
        try {
            downloadFile(localFilename,groupName,filePath);
        }catch (Exception e){
            e.printStackTrace();
        }
        return HeZhouResult.success();
    }

    /**
     * FastDFS获取文件名称
     */
    @RequestMapping(value = "/fastDFSGetFileName", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "上传文件到FastDFS", notes = "notes")
    public HeZhouResult<String> fastDFSGetFileName(String filePath) {
        String fileName = "";
        try {
            // 链接FastDFS服务器，创建tracker和Stroage
            ClientGlobal.initByProperties("application.properties");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();

            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);

            NameValuePair[] nvps = storageClient.get_metadata("group1", filePath);
            fileName = nvps[0].getName() + "." + nvps[0].getValue();
            if (nvps == null) {
                throw new IOException("文件" + filePath + "不存在");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return HeZhouResult.success(fileName);
    }

    /**
     * 从FastDFS下载文件
     *
     * @param localFilename  本地文件名
     * @param groupName      文件在FastDFS中的组名
     * @param remoteFilename 文件在FastDFS中的名称
     */
    public static void downloadFile(String localFilename, String groupName, String remoteFilename) {
        TrackerServer trackerServer;
        try {
            // 链接FastDFS服务器，创建tracker和Stroage
            ClientGlobal.initByProperties("application.properties");
            TrackerClient trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
        } catch (IOException | MyException e) {
            log.error("error", e);
            return;
        }
        StorageClient storageClient = new StorageClient(trackerServer, null);
        //拿到上传时存储的文件名
        NameValuePair[] nvps = new NameValuePair[0];
        try {
            nvps = storageClient.get_metadata("group1", remoteFilename);
            localFilename = localFilename + "/"+ nvps[0].getName() + "." + nvps[0].getValue();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        File file = new File(localFilename);
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
            byte[] content = storageClient.download_file(groupName, remoteFilename);
            if (content == null || content.length == 0) {
                log.error("文件大小为空！");
                boolean flag = file.delete();
                log.info("删除文件结果：{}", flag);
                return;
            }
            bos.write(content);
            log.info("成功下载文件： " + localFilename);
        } catch (IOException | MyException e) {
            log.error("error", e);
        } finally {
            closeTrackerServer(trackerServer);
        }
    }

    /**
     * FastDFS获取将上传文件信息
     */
    @RequestMapping(value = "/fastDFSGetFileInfo", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "上传文件到FastDFS", notes = "notes")
    public HeZhouResult<FileInfo> fastDFSGetFileInfo(String filePath) {
        try {
            // 链接FastDFS服务器，创建tracker和Stroage
            ClientGlobal.initByProperties("application.properties");
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();

            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);

            FileInfo fi = storageClient.get_file_info("group1", filePath);
            if (fi == null) {
                throw new IOException("文件" + filePath + "不存在");
            }
            return HeZhouResult.success(fi);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return HeZhouResult.success(null);
    }

    private static void closeTrackerServer(TrackerServer trackerServer) {
        try {
            if (trackerServer != null) {
                log.info("关闭trackerServer连接");
                trackerServer.close();
            }
        } catch (IOException e) {
            log.error("error", e);
        }
    }
}
